package ie.timalb.chess.main.core.temp;

import ie.timalb.chess.main.core.exceptions.SquareOutOfRangeException;
import ie.timalb.chess.main.core.movement.Location;
import ie.timalb.chess.main.core.movement.MovementDescriptor;
import ie.timalb.chess.main.core.squares.Square;

import java.util.Iterator;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

public class SquareIterator implements Iterator<Square> {
	private Squares squares;
	protected MovementDescriptor direction;
	protected Square currentSquare;
	protected Square sourceSquare;
	protected Square destinySquare;

	public SquareIterator(Squares squares, MovementDescriptor direction, Square sourceSquare, Square destinySquare) {
		super ();
		setSquares(squares);
		setCurrentSquare(null);
		setDirection(direction);
		setSourceSquare(sourceSquare);
		setDestinySquare(destinySquare);
	}

	public boolean hasNext() {
		if (nextDo() == null) {
			return false;
		}else
		{
			return true;
		}		
	}

	public Square next() {
		Square backup = getCurrentSquare();
		Square tmp = nextDo ();
		
		if (tmp!=null){
			setCurrentSquare(tmp);
			return getCurrentSquare();
		}else{
			setCurrentSquare(backup);
			return null;
		}
	}
	
	private Square nextDo (){
		
		Square next = null;		
		
		if (getCurrentSquare() == null)
		{
			//Getting the first element.
			next = getSourceSquare();
		}else if (getCurrentSquare().equals(getDestinySquare())){
			next = null;
		}else{				
			Location nextLocation;
			try {
				nextLocation = getCurrentSquare().getNextSquare(getDirection());
				next = getSquares().getSquare(nextLocation);
			} catch (SquareOutOfRangeException e) {
				next = null;
			}				
		}			
		
		return next;
	}

	@Override
	public void remove() {
		throw new NotImplementedException();
	}

	protected Squares getSquares() {
		return squares;
	}

	protected void setSquares(Squares squares) {
		this.squares = squares;
	}

	private MovementDescriptor getDirection() {
		return direction;
	}

	protected Square getCurrentSquare() {
		return currentSquare;
	}

	private void setCurrentSquare(Square currentSquare) {
		this.currentSquare = currentSquare;
	}

	private void setDirection(MovementDescriptor direction) {
		this.direction = direction;
	}

	private Square getSourceSquare() {
		return sourceSquare;
	}

	private void setSourceSquare(Square sourceSquare) {
		this.sourceSquare = sourceSquare;
	}

	private Square getDestinySquare() {
		return destinySquare;
	}

	private void setDestinySquare(Square destinySquare) {
		this.destinySquare = destinySquare;
	}
}